package com.tianchi.lexiang.background;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.net.EthernetManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.CheckedTextView;
import android.widget.EditText;
import android.content.Context;
import android.content.Intent;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import android.content.IntentFilter;
import android.content.BroadcastReceiver;

import com.tianchi.lexiang.R;

public class NetworkSetting extends Activity implements View.OnClickListener {
	private static final String TAG = "NetworkSetting";
	private CheckedTextView openAp;
	private CheckedTextView openEth;
	private Spinner ethMode;
	private TextView staticIPSetting;
	private Button backBtn;
	
	private Handler handler = new Handler();
	
	private int[] staticIPViews = {R.id.ip , R.id.netmask, R.id.gateway, R.id.dns};
	private String[] staticIPPersistKeys = {"ethernet_static_ip" , "ethernet_static_netmask" , "ethernet_static_gateway" , "ethernet_static_dns1"};
	
	private WifiManager wifiManager;
	private EthernetManager mEthernetManager;
	private SharedPreferences pref;
	public static final String STATIC_BACKUP = "network_config";
	public static final String WIFI_AP_ENABLE = "wifi_ap_enable";
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.net_setting);
		openAp = (CheckedTextView) findViewById(R.id.openAp);
		openAp.setOnClickListener(this);
		openEth = (CheckedTextView) findViewById(R.id.openEth);
		openEth.setOnClickListener(this);	
		backBtn = (Button)findViewById(R.id.back_btn);
		backBtn.setOnClickListener(this);

		ethMode = (Spinner) findViewById(R.id.ethMode);
		ethMode.setOnItemSelectedListener(new OnItemSelectedListener() {
			@Override
			public void onItemSelected(AdapterView<?> parent, View view,
					int position, long id) {
				Log.d(TAG, "[onItemSelected] position=>" + position);
				Settings.System.putInt(getContentResolver(), "ethernet_use_static_ip", position);
				staticIPSetting.setEnabled(position==1);
				int bgId = (position==1) ? android.R.drawable.alert_light_frame : android.R.drawable.alert_dark_frame;
				staticIPSetting.setBackgroundResource(bgId);
			}
			
			@Override
			public void onNothingSelected(AdapterView<?> arg0) {
				
			}
		});
		
		staticIPSetting = (TextView) findViewById(R.id.staticIPSetting);
		staticIPSetting.setOnClickListener(this);
		
		wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
		mEthernetManager = (EthernetManager) getSystemService(ETHERNET_SERVICE);
		pref = getSharedPreferences(STATIC_BACKUP, MODE_WORLD_READABLE);
	}

	public void wifiApClick() {
		Log.d(TAG, "[wifiApClickListener]");
		openAp.toggle();
		openAp.setEnabled(false);
		int stringId = openAp.isChecked() ? R.string.opening_ap
				: R.string.closing_ap;
		openAp.setText(stringId);
		
		setWifiApEnabled(openAp.isChecked());
		
	}

	@Override
	protected void onResume() {
		super.onResume();
		int dhcpOrStatic = Settings.System.getInt(getContentResolver(), "ethernet_use_static_ip" , 0);
		ethMode.setSelection(dhcpOrStatic);
		openEth.setChecked(mEthernetManager.isEthernetEnabled());
		runOnUiThread(new OpenEthUIChanger());
		resumeWifiApState();
	}
	
	private void resumeWifiApState(){
		IntentFilter mIntentFilter = new IntentFilter(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
		registerReceiver(mReceiver, mIntentFilter);
	}

	@Override
	protected void onPause() {
		super.onPause();
		unregisterReceiver(mReceiver);
	}

    public boolean setWifiApEnabled(boolean enabled) {  
        if (enabled) { 
            wifiManager.setWifiEnabled(false);  
        }  
        try {  
            WifiConfiguration apConfig = new WifiConfiguration();  
            apConfig.SSID = "tianchi";  
            apConfig.preSharedKey="121221321";  
            Method method = wifiManager.getClass().getMethod(  
                    "setWifiApEnabled", WifiConfiguration.class, Boolean.TYPE);  
            return (Boolean) method.invoke(wifiManager, apConfig, enabled);  
        } catch (Exception e) {  
            return false;  
        }  
    }  
	
	private class OpenWifiApUIChanger implements Runnable {
		@Override
		public void run() {
			openAp.setEnabled(true);
			int stringId = openAp.isChecked() ? R.string.ap_opened
					: R.string.ap_closed;
			openAp.setText(stringId);
		}
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.openAp:
			wifiApClick();
			break;
		case R.id.openEth:
			ethClick();
			break;
		case R.id.staticIPSetting:
			staticIPSettingClick();
			break;
		case R.id.back_btn:
			NetworkSetting.this.finish();
			break;
		default:
			break;
		}
	}
	
	public void ethClick() {
		Log.d(TAG, "[ethClick]");
		openEth.toggle();
		openEth.setEnabled(false);
		int stringId = openEth.isChecked() ? R.string.opening_eth
				: R.string.closing_eth;
		openEth.setText(stringId);
		ethernetEnable(openEth.isChecked());
		handler.postDelayed(new OpenEthUIChanger(), 2000);
	}
	
	private void ethernetEnable(boolean enable){
		Log.d(TAG, "[ethernetEnable]");
		mEthernetManager.setEthernetEnabled(enable);
	}
	
	public void staticIPSettingClick(){
		Log.d(TAG, "[staticIPSettingListener]");
		createStaticIPDialog();
	}
	
	private void restoreStaticIP(View parent){
		int length = staticIPViews.length;
		for (int i = 0; i < length; i++) {
			String value = pref.getString(staticIPPersistKeys[i], "");
			((EditText)parent.findViewById(staticIPViews[i])).setText(value);
		}
	}
	
	private void createStaticIPDialog(){
		final View dialogView = LayoutInflater.from(this).inflate(R.layout.static_ip, null);
		restoreStaticIP(dialogView);
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setTitle(R.string.static_ip_set);
		builder.setView(dialogView);
		builder.setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				Field field;
				try {
					field = AlertDialog.class.getSuperclass().getDeclaredField("mShowing");
					field.setAccessible(true);
					int length = staticIPViews.length;
					boolean ipValid = true;
					for (int i = 0; i < length; i++) {
						String value = ((EditText)dialogView.findViewById(staticIPViews[i])).getText().toString().trim();
						boolean res = isIpFormat(value);
						if (!res) {
							ipValid = false;
							break;
						}
					}
					
					if (!ipValid) {
						field.set(dialog, false);
						Toast.makeText(NetworkSetting.this, R.string.ip_error, Toast.LENGTH_SHORT).show();
						return;
					}		
					field.set(dialog, true);
				} catch (SecurityException e) {
					e.printStackTrace();
				} catch (NoSuchFieldException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				}
				
				int length = staticIPViews.length;
	            
				for (int i = 0; i < length; i++) {
					String value = ((EditText)dialogView.findViewById(staticIPViews[i])).getText().toString().trim();
					Log.d(TAG, "[createStaticIPDialog] will set " + staticIPPersistKeys[i] + ";;value==>" + value);
					pref.edit().putString(staticIPPersistKeys[i], value).commit();
					Settings.System.putString(getContentResolver(), staticIPPersistKeys[i], value);
				}
				dialog.dismiss();
			}
		});
		builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				dialog.dismiss();
			}
		});
		builder.create();
		builder.show();
	}

	private boolean isIpFormat(String s){
		String regex = "(((2[0-4]\\d)|(25[0-5]))|(1\\d{2})|([1-9]\\d)|(\\d))[.](((2[0-4]\\d)|(25[0-5]))|(1\\d{2})|([1-9]\\d)|(\\d))[.](((2[0-4]\\d)|(25[0-5]))|(1\\d{2})|([1-9]\\d)|(\\d))[.](((2[0-4]\\d)|(25[0-5]))|(1\\d{2})|([1-9]\\d)|(\\d))";
		Pattern p = Pattern.compile(regex);
		Matcher m = p.matcher(s);
		return m.matches();
	}
	
	private class OpenEthUIChanger implements Runnable {
		@Override
		public void run() {
			openEth.setEnabled(true);
			ethMode.setEnabled(openEth.isChecked());
			int stringId = openEth.isChecked() ? R.string.eth_opened
					: R.string.eth_closed;
			openEth.setText(stringId);
			if (!openEth.isChecked()) {
				staticIPSetting.setBackgroundResource(android.R.drawable.alert_dark_frame);
			}else{
				if (Settings.System.getInt(getContentResolver(), "ethernet_use_static_ip", 0) == 1) {
					staticIPSetting.setBackgroundResource(android.R.drawable.alert_light_frame);
				}
			}
		}
	}
	
	private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (WifiManager.WIFI_AP_STATE_CHANGED_ACTION.equals(action)) {
                handleWifiApStateChanged(intent.getIntExtra(
                        WifiManager.EXTRA_WIFI_AP_STATE, WifiManager.WIFI_AP_STATE_FAILED));
            } 
        }
    };
    
    private void handleWifiApStateChanged(int state) {
    	openAp.setEnabled(true);
        switch (state) {
            case WifiManager.WIFI_AP_STATE_ENABLED:
				Log.d(TAG, "[handleWifiApStateChanged] WIFI_AP_STATE_ENABLED");
            	openAp.setChecked(true);
    			openAp.setText(R.string.ap_opened);
    			pref.edit().putBoolean(WIFI_AP_ENABLE, true).commit();
                break;
            case WifiManager.WIFI_AP_STATE_DISABLED:
				Log.d(TAG, "[handleWifiApStateChanged] WIFI_AP_STATE_DISABLED");
    			openAp.setText(R.string.ap_closed);
            	openAp.setChecked(false);
            	pref.edit().putBoolean(WIFI_AP_ENABLE, false).commit();
                break;
            default:
				Log.d(TAG, "[handleWifiApStateChanged] default");
            	openAp.setChecked(false);
            	pref.edit().putBoolean(WIFI_AP_ENABLE, false).commit();
            	break;
        }
    }	
}
